home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine CD 1995 / Archive Magazine CD 1995.iso / discs / prog_disc / volume_5 / issue_08 / boota / C-source / c / ARCtoIBM < prev    next >
Encoding:
Text File  |  1991-12-16  |  19.7 KB  |  494 lines

  1. /* > c.ARCtoIBM - (c) Paul Witheridge - Version 2.00 - 06 Dec 1991   */
  2.  
  3. /*===================================================================*/
  4. /*                                                                   */
  5. /*  ARCtoIBM                                                         */
  6. /*  --------                                                         */
  7. /*                                                                   */
  8. /*  This utility converts ARC ASCII files to IBM ASCII files by:     */
  9. /*                                                                   */
  10. /*    1.  converting LF to CR/LF                                     */
  11. /*    2.  optionally adding a trailing CTRL-Z (0x1A)                 */
  12. /*                                                                   */
  13. /*  It can process multiple files if a wildcarded filename is        */
  14. /*  specified or if a directory name is specified. For a wildcarded  */
  15. /*  filename it processes all files with names that match the        */
  16. /*  pattern. For a directory it processes all files within the       */
  17. /*  directory. Directory names can also be wildcarded.               */
  18. /*                                                                   */
  19. /*-------------------------------------------------------------------*/
  20. /*                                                                   */
  21. /*  COPYRIGHT NOTICE                                                 */
  22. /*                                                                   */
  23. /*  ARCtoIBM is subject to Copyright.                                */
  24. /*                                                                   */
  25. /*  Permission is granted by the author to any recipient of this     */
  26. /*  material to use and make/disseminate copies of the application   */
  27. /*  provided that no charges are made for doing so (other than to    */
  28. /*  cover any cost of media or postage) and that this notice is      */
  29. /*  included with all copies.                                        */
  30. /*                                                                   */
  31. /*===================================================================*/
  32.  
  33. #include "kernel.h"                     /* ARC specifics             */
  34. #include <ctype.h>                      /* Character handling        */
  35. #include <stddef.h>                     /* Standard definitions      */
  36. #include <stdio.h>                      /* Input/output              */
  37. #include <stdlib.h>                     /* General utilities         */
  38. #include <string.h>                     /* String handling           */
  39.  
  40. #include "GetDirs.h"                    /* GetDirs header            */
  41. #include "ArgFuncs.h"                   /* Arg functions etc         */
  42. #include "Useful.h"                     /* Useful defns              */
  43.  
  44. /*-------------------------------------------------------------------*/
  45. /*  Global data declarations and definitions.                        */
  46. /*-------------------------------------------------------------------*/
  47.  
  48. #define maxlines 4096                   /* Max no lines to convert   */
  49.  
  50. static char flags = '\0' ;              /* Processing flags          */
  51.  
  52.   #define flgfnd 0x01                   /* Found file to process     */
  53.   #define flgovr 0x10                   /* Overwrite mode            */
  54.   #define flgrcs 0x20                   /* Recursive mode            */
  55.   #define flgtst 0x40                   /* Test mode                 */
  56.   #define flgx1a 0x80                   /* CTRL-Z required           */
  57.  
  58. static int filecount = 0 ;              /* Count of files processed. */
  59.  
  60. static const char *argptr = NULL ;      /* Pointer to file spec.     */
  61. static const char *pfxptr = "_" ;       /* Pointer to output prefix  */
  62.  
  63. /*-------------------------------------------------------------------*/
  64. /*  Declare functions local in scope to this file.                   */
  65. /*-------------------------------------------------------------------*/
  66.  
  67. static enum boolean cnvtfunc(           /* Convert function          */
  68.   const char *path,
  69.   direntry *ptr) ;
  70.  
  71. /*===================================================================*/
  72. /*                                                                   */
  73. /*  Main program                                                     */
  74. /*  ------------                                                     */
  75. /*                                                                   */
  76. /*  Analyse arguments. Then call the "GetDirentrys" function to      */
  77. /*  read all the file-names in the specified directory (plus any     */
  78. /*  sub directories). Provide "GetDirentrys" with pointer to         */
  79. /*  function to process the specified files.                         */
  80. /*                                                                   */
  81. /*===================================================================*/
  82.  
  83. int main( 
  84.   const int argc,                     /* Number of arguments         */
  85.   const char *const argv[])           /* Array of pointers to args   */
  86. {
  87.   /*-----------------------------------------------------------------*/
  88.   /*  Local definitions.                                             */
  89.   /*-----------------------------------------------------------------*/
  90.  
  91.   int returncode ;
  92.  
  93.   static const char options[] =  /* Used to match option argument    */
  94.   {
  95.     'O',                            /* Overwrite mode                */
  96.     'P',                            /* Output prefix                 */
  97.     'R',                            /* Recursive mode                */
  98.     'T',                            /* Test mode                     */
  99.     'Z',                            /* CTRL-Z required               */
  100.     '0'                             /* Null byte terminator          */
  101.   } ;
  102.  
  103.   static const char **posval[] = /* Ptrs to ptrs to posit'nal values */ 
  104.   {
  105.     &argptr
  106.   } ;
  107.  
  108.   static const char optflags[] = /* Used to set option flags         */
  109.   {
  110.     flgovr,                         /* Overwrite mode                */
  111.     0,                              /* Output prefix                 */
  112.     flgrcs,                         /* Recursive mode                */
  113.     flgtst,                         /* Test mode                     */
  114.     flgx1a,                         /* CTRL-Z required               */
  115.   } ;
  116.  
  117.   static const char **optval[] = /* Ptrs to ptrs to option values    */
  118.   {
  119.     NULL,                           /* No value allowed              */
  120.     &pfxptr,                        /* Output file prefix            */
  121.     NULL,                           /* No value allowed              */
  122.     NULL,                           /* No value allowed              */
  123.     NULL,                           /* No value allowed              */
  124.   } ;
  125.  
  126.   static const char helpdata[] = /* Help text to be displayed        */
  127.  
  128.     "ARCtoIBM inserts carriage return characters (CR = hex 0D) in "
  129.     "front of all linefeed characters (LF = hex 0A) found in the "
  130.     "file(s) being processed (unless the LF is already preceded by "
  131.     "a CR). It can also optionally add a CTRL-Z (hex 1A) to the end "
  132.     "of each file (unless already present).\x1f"
  133.     "\x1f"
  134.     "WARNING:\x01" "This utility converts files IN-PLACE if the "
  135.     "'-o' option is used to replace the input file with the "
  136.     "converted file.\x1f"
  137.     "\x1f"
  138.     "Syntax:\x01" "*ARCtoIBM  [path.]object  [options]\x1f"
  139.     "\x1f"
  140.     "object:\x01" "Specifies one of the following:\x1f"
  141.     "\x01" "(a) a single non-wildcarded file name\x1f"
  142.     "\x01" "(b) a single non-wildcarded directory name\x1f"
  143.     "\x01" "(c) a wildcarded name.\x1f"
  144.     "\x1f"
  145.     "\x01" "In case (a) the file specified is converted.\x1f"
  146.     "\x1f"
  147.     "\x01" "In case (b) all files in the specified directory are "
  148.     "converted. If the RECURSION option is specified all files "
  149.     "in all subdirectories are also converted\x1f"
  150.     "\x1f"
  151.     "\x01" "In case (c) all matching files are converted. If no "
  152.     "matching files are found, then the first matching directory "
  153.     "name is taken and all files therein are converted. If the "
  154.     "RECURSION option is specified, all matching files are "
  155.     "converted plus all files in all subdirectories.\x1f"
  156.     "\x1f"
  157.     "path:\x01" "Specifies the directory to be searched for the "
  158.     "object file/directory. If omitted the current directory "
  159.     "is searched.\x1f"
  160.     "\x1f"
  161.     "options:\x01" "Specifies processing options which can be one "
  162.     "or more ofthe following:\x1f"
  163.     "\x1f"
  164.     "\x01" "-o\x02" "-\x03" "OVERWRITE mode; output file will have "
  165.     "same name and will replace input file.\x1f"
  166.     "\x1f"
  167.     "\x01" "-p xxx\x02" "-\x03" "specify PREFIX which will be used "
  168.     "to create name for output file if '-o' is not specified; "
  169.     "'xxx' can be one or more characters including directory "
  170.     "specification (e.g. 'converted.'); if not specified a default "
  171.     "of '_' is used.\x1f"
  172.     "\x1f"
  173.     "\x01" "-r\x02" "-\x03" "RECURSION mode which causes all "
  174.     "files in all subdirectories to be converted.\x1f"
  175.     "\x1f"
  176.     "\x01" "-t\x02" "-\x03" "TEST mode; a list of files to be "
  177.     "converted is displayed but no output is actually written; "
  178.     "useful for checking when specifying a directory or "
  179.     "wildcarded filename.\x1f"
  180.     "\x1f"
  181.     "\x01" "-z\x02" "-\x03" "CTRL-Z required; a hex 1A end-of-file "
  182.     "character is added to the end of each file unless already "
  183.     "present.\x1f"
  184.     "\x1f"
  185.     "ARCtoIBM - copyright Paul Witheridge, 1991\x1f"
  186.     "\x1f" ;
  187.  
  188.   static const unsigned char helptabs[] =  /* Help text tab settings */
  189.   {
  190.     1,10,17,19
  191.   } ;
  192.  
  193.   /*-----------------------------------------------------------------*/
  194.   /*  Executable statements                                          */
  195.   /*-----------------------------------------------------------------*/
  196.  
  197.   puts("\nARCtoIBM Version 2.00 - 06 December 1991\n") ;
  198.  
  199.   /*-----------------------------------------------------------------*/
  200.   /*  Analyse arguments for file-name and option flags.              */
  201.   /*-----------------------------------------------------------------*/
  202.  
  203.   analargs(argc,argv,1,posval,options,&flags,optflags,optval) ;
  204.  
  205.   /*-----------------------------------------------------------------*/
  206.   /*  Set paged scrolling mode                                       */
  207.   /*-----------------------------------------------------------------*/
  208.  
  209.   _kernel_oswrch(12) ;
  210.   _kernel_oswrch(14) ;
  211.  
  212.   puts(" PRESS SHIFT KEY TO ALLOW WINDOW TO SCROLL\n") ;
  213.   
  214.   /*-----------------------------------------------------------------*/
  215.   /*  If no file name operand just display help text.                */
  216.   /*-----------------------------------------------------------------*/
  217.  
  218.   if ( argptr == NULL )
  219.   {
  220.     displaytext(helpdata,helptabs) ;
  221.     _kernel_oswrch(15) ;
  222.     return 0 ;
  223.   }
  224.  
  225.   /*-----------------------------------------------------------------*/
  226.   /*  If TEST MODE issue message.                                    */
  227.   /*-----------------------------------------------------------------*/
  228.  
  229.   if ( flags & flgtst )
  230.   {
  231.     puts("TEST MODE (files will be identified, not converted).\n") ;
  232.   }
  233.  
  234.   /*-----------------------------------------------------------------*/
  235.   /*  Invoke GetDirs function to read the directory entry(s) of the  */
  236.   /*  file(s) to be processed. Pass it a pointer of a processing     */
  237.   /*  function to be called.                                         */
  238.   /*-----------------------------------------------------------------*/
  239.  
  240.   returncode = 4 ;
  241.  
  242.   if ( getdirentrys(argptr,
  243.        ( flags & flgrcs ? RECURSE_ALWAYS : RECURSE_ONCE ),cnvtfunc) )
  244.   {
  245.     if ( flags & flgfnd )
  246.     {
  247.       printf("\n%d file(s) ",filecount) ;
  248.       if ( flags & flgtst )
  249.       {
  250.         printf("would be ") ;
  251.       }
  252.       puts("converted.\n") ;
  253.       returncode = 0 ;
  254.     }
  255.     else
  256.     {
  257.       printf("No files found matching '%s'\n",argptr) ;
  258.       beep() ;
  259.     }
  260.   }
  261.   
  262.   /*-----------------------------------------------------------------*/
  263.   /*  Return to caller. All done.                                    */
  264.   /*-----------------------------------------------------------------*/
  265.  
  266.   _kernel_oswrch(15) ;
  267.   return returncode ;
  268. }
  269.  
  270. /*===================================================================*/
  271. /*                                                                   */
  272. /*  cnvtfunc  -  perform actual file conversion                      */
  273. /*  --------                                                         */
  274. /*                                                                   */
  275. /*  This function is called by the "getdirentrys" function for each  */
  276. /*  file-name that it encounters.                                    */
  277. /*                                                                   */
  278. /*===================================================================*/
  279.  
  280. static enum boolean cnvtfunc(
  281.   const char *path,                   /* Pointer to path name.       */
  282.   direntry *ptr)                      /* Pointer to direntry info.   */
  283.  
  284. {
  285.   /*-----------------------------------------------------------------*/
  286.   /*  Local definitions.                                             */
  287.   /*-----------------------------------------------------------------*/
  288.  
  289.   char *infile ;                      /* Ptr to path + leafname      */
  290.   char *oufile ;                      /* Ptr tp path + leafname      */
  291.   int result ;                        /* Result from OS-File SWI     */
  292.   char *workarea ;                    /* Ptr to start of work area   */
  293.   char *workend ;                     /* Ptr to end of work area     */
  294.   char *iptr ;                        /* Working pointer             */
  295.   char *optr ;                        /* Working pointer             */
  296.   register int thischar ;             /* Current character           */
  297.   register int prevchar ;             /* Previous character          */
  298.  
  299.   _kernel_osfile_block osfileblock ;  /* OS_File parameter block     */
  300.  
  301.   /*-----------------------------------------------------------------*/
  302.   /*  Translate table - IBM ASCII to ARC ASCII                       */
  303.   /*-----------------------------------------------------------------*/
  304.   
  305.   static unsigned char trantabl[256] = /* No-op as it  stands        */
  306.   {
  307.       0,   1,   2,   3,   4,   5,   6,   7,
  308.       8,   9,  10,  11,  12,  13,  14,  15,
  309.      16,  17,  18,  19,  20,  21,  22,  23,
  310.      24,  25,  26,  27,  28,  29,  30,  31,
  311.      32,  33,  34,  35,  36,  37,  38,  39,
  312.      40,  41,  42,  43,  44,  45,  46,  47,
  313.      48,  49,  50,  51,  52,  53,  54,  55,
  314.      56,  57,  58,  59,  60,  61,  62,  63,
  315.      64,  65,  66,  67,  68,  69,  70,  71,
  316.      72,  73,  74,  75,  76,  77,  78,  79,
  317.      80,  81,  82,  83,  84,  85,  86,  87,
  318.      88,  89,  90,  91,  92,  93,  94,  95,
  319.      96,  97,  98,  99, 100, 101, 102, 103,
  320.     104, 105, 106, 107, 108, 109, 110, 111,
  321.     112, 113, 114, 115, 116, 117, 118, 119,
  322.     120, 121, 122, 123, 124, 125, 126, 127,
  323.     128, 129, 130, 131, 132, 133, 134, 135,
  324.     136, 137, 138, 139, 140, 141, 142, 143,
  325.     144, 145, 146, 147, 148, 149, 150, 151,
  326.     152, 153, 154, 155, 156, 157, 158, 159,
  327.     160, 161, 162, 163, 164, 165, 166, 167,
  328.     168, 169, 170, 171, 172, 173, 174, 175,
  329.     176, 177, 178, 179, 180, 181, 182, 183,
  330.     184, 185, 186, 187, 188, 189, 190, 191,
  331.     192, 193, 194, 195, 196, 197, 198, 199,
  332.     200, 201, 202, 203, 204, 205, 206, 207,
  333.     208, 209, 210, 211, 212, 213, 214, 215,
  334.     216, 217, 218, 219, 220, 221, 222, 223,
  335.     224, 225, 226, 227, 228, 229, 230, 231,
  336.     232, 233, 234, 235, 236, 237, 238, 239,
  337.     240, 241, 242, 243, 244, 245, 246, 247,
  338.     248, 249, 250, 251, 252, 253, 254, 255 
  339.   } ;
  340.  
  341.   /*-----------------------------------------------------------------*/
  342.   /*  If test mode display heading on first time through             */
  343.   /*-----------------------------------------------------------------*/
  344.  
  345.   if ( (flags & flgtst) && !(flags & flgfnd) )
  346.   {
  347.     puts("The following files would be converted:\n") ;
  348.   }
  349.  
  350.   flags |= flgfnd ;
  351.  
  352.   /*-----------------------------------------------------------------*/
  353.   /*  Create input and output filespecs                              */
  354.   /*-----------------------------------------------------------------*/
  355.   
  356.   if ( ( infile = malloc(2 * (strlen(path) + strlen(ptr->name) + 1)
  357.                          + strlen(pfxptr) ) ) == NULL )
  358.   {
  359.     puts("Out of memory") ;
  360.     return FALSE ;
  361.   } 
  362.   
  363.   oufile = infile + sprintf(infile,"%s%s",path,ptr->name) + 1 ;
  364.   sprintf(oufile,"%s%s%s",path,flags & flgovr ? "" : pfxptr,ptr->name) ;
  365.   
  366.   /*-----------------------------------------------------------------*/
  367.   /*  Check input file has non-zero length                           */
  368.   /*-----------------------------------------------------------------*/
  369.  
  370.   if ( ptr->length == 0 )
  371.   {
  372.     printf("'%s' is empty\n",infile) ;
  373.   }
  374.  
  375.   /*-----------------------------------------------------------------*/
  376.   /*  Allocate memory for file and load file                         */
  377.   /*-----------------------------------------------------------------*/
  378.  
  379.   if ( (workarea = malloc((ptr->length) + maxlines + 1) ) == NULL )
  380.   {
  381.     printf("'%s' too large to load",infile) ;
  382.     goto error4 ;
  383.   }
  384.  
  385.   optr = workarea ;
  386.   iptr = workarea + maxlines ;
  387.   workend = iptr + ptr->length ;
  388.  
  389.   osfileblock.load  = (int)iptr ;
  390.   osfileblock.exec  = 0 ;
  391.   result = _kernel_osfile(16,infile,&osfileblock) ;
  392.  
  393.   if (result == _kernel_ERROR)
  394.   {
  395.     printf("'%s' load failed - %s\n",infile,
  396.           _kernel_last_oserror()->errmess) ;
  397.     goto error3 ;
  398.   }
  399.  
  400.   /*-----------------------------------------------------------------*/
  401.   /*  Convert all LF to CR/LF and add trailing CTRL-Z if required.   */
  402.   /*-----------------------------------------------------------------*/
  403.  
  404.   prevchar = 0 ;
  405.   
  406.   while ( iptr < workend )
  407.   {
  408.     *optr = thischar = trantabl[*iptr] ;
  409.     iptr++ ;
  410.     if ( thischar == 0x0A && prevchar != 0x0D )
  411.     {
  412.       *optr = 0x0D ;
  413.       optr++ ;
  414.       if ( optr >= iptr )
  415.       {
  416.         printf("'%s' conversion failed - too many lines\n",infile) ;
  417.         goto error3 ;
  418.       }
  419.       *optr = 0x0A ;
  420.     }
  421.     optr++ ;
  422.     prevchar = thischar ;
  423.   }
  424.   
  425.   if ( flags & flgx1a && prevchar != 0x1A )
  426.   {
  427.     *optr = 0x1A ;
  428.     optr++ ;
  429.   }  
  430.   
  431.   /*-----------------------------------------------------------------*/
  432.   /*  If not test mode, save modified file                           */
  433.   /*-----------------------------------------------------------------*/
  434.  
  435.   if ( !(flags & flgtst) )
  436.   {
  437.     osfileblock.load = ptr->load ;
  438.     osfileblock.exec   = ptr->exec ;
  439.     osfileblock.start  = (int)workarea ;
  440.     osfileblock.end    = (int)optr ;
  441.  
  442.     result = _kernel_osfile(0,oufile,&osfileblock) ;
  443.  
  444.     if (result == _kernel_ERROR)
  445.     {
  446.       printf("'%s' save failed - %s\n",oufile,
  447.              _kernel_last_oserror()->errmess);
  448.       goto error3 ;
  449.     }
  450.   }
  451.  
  452.   /*-----------------------------------------------------------------*/
  453.   /*  Valid conversion - bump file count                             */
  454.   /*-----------------------------------------------------------------*/
  455.   
  456.   filecount++ ;
  457.  
  458.   /*-----------------------------------------------------------------*/
  459.   /*  Display file name (plus "converted" if not test mode)          */
  460.   /*-----------------------------------------------------------------*/
  461.  
  462.   printf("'%s'",infile) ;
  463.   if ( !(flags & flgtst) )
  464.   {
  465.     printf(" converted") ;
  466.     if ( !(flags & flgovr) )
  467.     {
  468.       printf(" and saved as '%s'",oufile) ;
  469.     }
  470.   }
  471.   putchar('\n') ;
  472.  
  473.   /*-----------------------------------------------------------------*/
  474.   /*  Free work area and return with good completion code            */
  475.   /*-----------------------------------------------------------------*/
  476.  
  477.   free(workarea) ;
  478.   free(infile) ;
  479.  
  480.   return TRUE ;
  481.  
  482.   /*-----------------------------------------------------------------*/
  483.   /*  Error exits                                                    */
  484.   /*-----------------------------------------------------------------*/
  485.  
  486.   error3: free(workarea) ;
  487.   error4: free(infile) ;
  488.           beep() ;
  489.  
  490.   return FALSE ;
  491. }
  492.  
  493. /*=====================================================================*/
  494.